﻿/*
 * By David Barrett, Microsoft Ltd. 2012. Use at your own risk.  No warranties are given.
 * 
 * DISCLAIMER:
 * THIS CODE IS SAMPLE CODE. THESE SAMPLES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
 * MICROSOFT FURTHER DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS FOR
 * A PARTICULAR PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF THE SAMPLES REMAINS WITH YOU. IN NO EVENT SHALL
 * MICROSOFT OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
 * BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE
 * SAMPLES, EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION
 * OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
 * */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Xml;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Reflection;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using SOAP_Test_Application.EWSTools;

namespace SOAP_Test_Application
{
    public partial class FormMain : Form
    {
        private FormListener _httpListener = null;
        private FormLogViewer _logViewer = null;
        private FormEWSAutodiscover _autodiscoverForm = null;
        private ClassLogger _logger = null;
        private string _userSMTPAddress = "";
        private string _templatePath = "";
        private Point _cursorTracking;  // Used when we need to track the mouse pointer position
        private CookieCollection _responseCookies = null;

        public FormMain()
        {
            InitializeComponent();

            this.Text = "SOAP Test Application v" + Application.ProductVersion;

            // Hook up the cert callback.  
            ServicePointManager.ServerCertificateValidationCallback =
                delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
                {
                    // Validate the certificate and return true or false as appropriate.  
                    // Note that it not a good practice to always return true because not  
                    // all certificates should be trusted.  
                    return true;
                };
            PopulateEWSAddress();
            UpdateTextBoxState();
            _logger = new ClassLogger(Path.GetDirectoryName(Application.ExecutablePath) + "\\SOAP Conversation.log");
            _logger.StoreLogs = true;
            ReadAvailableTemplates();

        }

        ~FormMain()
        {
            try
            {
                _httpListener.Dispose();
                _logger = null;
                GC.Collect();
            }
            catch { }
        }

        public FormListener HTTPListener
        {
            get
            {
                if (_httpListener == null)
                {
                    _httpListener = new FormListener(new ClassLogger(Path.GetDirectoryName(Application.ExecutablePath) + "\\Listener.log"));
                    _httpListener.Show();
                }
                if (_httpListener.IsDisposed)
                {
                    _httpListener = new FormListener(new ClassLogger(Path.GetDirectoryName(Application.ExecutablePath) + "\\Listener.log"));
                    _httpListener.Show();
                }
                return _httpListener;
            }
        }

        private ICredentials CurrentCredentials
        {
            get
            {
                ICredentials oCredential;
                if (radioButtonDefaultCredentials.Checked)
                {
                    oCredential = CredentialCache.DefaultCredentials;
                }
                else
                {
                    oCredential = new NetworkCredential(textBoxUsername.Text, textBoxPassword.Text);
                    if (!String.IsNullOrEmpty(textBoxDomain.Text))
                       (oCredential as NetworkCredential).Domain = textBoxDomain.Text;
                    
                }
                return oCredential;
            }
        }

        private void PopulateEWSAddress()
        {
            // We will try to retrieve SMTP address of current user.

            try
            {
                // Populate domain first of all
                string sDomain;
                using (DirectoryEntry rootDSE = new DirectoryEntry("LDAP://RootDSE"))
                {
                    sDomain = rootDSE.Properties["defaultNamingContext"].Value.ToString();
                }

                if (sDomain == "") return;

                sDomain = sDomain.Replace("DC=", "").Replace(",", ".");
                textBoxDomain.Text = sDomain;

                //string sExchangeServer = "";
                using (DirectoryEntry userDE = new DirectoryEntry("LDAP://" + UserPrincipal.Current.DistinguishedName.ToString()))
                {
                    string sHomeMDB = userDE.Properties["homeMDB"].Value.ToString();
                    _userSMTPAddress = userDE.Properties["mail"].Value.ToString();

                    /*
                    using (DirectoryEntry oDE = new DirectoryEntry("LDAP://" + sHomeMDB))
                    {
                        string sOwningServer = oDE.Properties["msExchOwningServer"][0].ToString();

                        using (DirectoryEntry exchDE = new DirectoryEntry("LDAP://" + sOwningServer))
                        {
                            PropertyValueCollection oNetworkAddress = exchDE.Properties["networkAddress"];
                            foreach (object oProperty in oNetworkAddress)
                            {
                                string sPropVal = oProperty.ToString();
                                if (sPropVal.StartsWith("ncacn_ip_tcp:"))
                                {
                                    // This is the DNS name of the Exchange server
                                    sExchangeServer = sPropVal.Substring(13);
                                }
                            }
                        }
                    }
                     */
                }
                /*
                System.Net.IPHostEntry iph = System.Net.Dns.GetHostEntry(sExchangeServer);
                if (iph.AddressList.Length > 0)
                {
                    textBoxURL.Text = "https://" + sExchangeServer + "/EWS/Exchange.asmx";
                }
                */
            }
            catch
            {
                // Failed to resolve name, so don't update
                return;
            }
        }

        private void LogCredentials()
        {
            string sCredentialInfo = "";
            if (radioButtonDefaultCredentials.Checked)
            {
                sCredentialInfo += "Using default credentials" + Environment.NewLine;
                sCredentialInfo += "Username: " + Environment.UserName + Environment.NewLine;
                sCredentialInfo += "Domain: " + Environment.UserDomainName;
            }
            else
            {
                sCredentialInfo += "Using specific credentials" + Environment.NewLine;
                if (checkBoxForceBasicAuth.Checked)
                    sCredentialInfo += "Forcing BASIC AUTH" + Environment.NewLine;
                sCredentialInfo += "Username: " + textBoxUsername.Text + Environment.NewLine;
                sCredentialInfo += "Domain: " + textBoxDomain.Text;
            }
            _logger.Log(sCredentialInfo, "Request Credentials");
        }

        private void buttonSend_Click(object sender, EventArgs e)
        {
            if (checkBoxUpdateEWSHeader.Checked)
                UpdateSOAPHeader();
            string sSOAPRequest = richTextBoxRequest.Text;

            richTextBoxResponse.Text = "";
            richTextBoxResponse.Refresh();
            buttonSend.Enabled = false;
            bool bTriedBasicAuth = false;
            ClassSOAP oSOAP = null;
            while (!bTriedBasicAuth)
            {
                oSOAP = null;
                LogCredentials();
                if (radioButtonDefaultCredentials.Checked || (radioButtonSpecificCredentials.Checked && !checkBoxForceBasicAuth.Checked))
                {
                    oSOAP = new ClassSOAP(textBoxURL.Text, CurrentCredentials, _logger);
                }
                else
                {
                    // Forcing basic authentication
                    oSOAP = new ClassSOAP(textBoxURL.Text, textBoxUsername.Text, textBoxPassword.Text, _logger);
                    bTriedBasicAuth=true;
                }
                oSOAP.BypassWebProxy = checkBoxBypassProxySettings.Checked;
                if ((_responseCookies != null) && (checkBoxPersistCookies.Enabled && checkBoxPersistCookies.Checked))
                {
                    // Persist cookies
                    richTextBoxResponse.Text = oSOAP.SendRequest(sSOAPRequest, _responseCookies);
                }
                else
                    richTextBoxResponse.Text = oSOAP.SendRequest(sSOAPRequest);

                if (richTextBoxResponse.Text.StartsWith("Error occurred") && !checkBoxForceBasicAuth.Checked)
                {
                    // Check for auth error, then whether we are using basic auth
                    bTriedBasicAuth = true;
                    if (richTextBoxResponse.Text.Contains("401"))
                    {
                        if (oSOAP.LastResponseHeaders.AllKeys.Contains("WWW-Authenticate"))
                        {
                            // We've been sent an authenticate header, so check if BASIC is an option
                            string sAuth = oSOAP.LastResponseHeaders["WWW-Authenticate"];

                            // If basic auth is specified, AND we are using HTTPS, then automatically retry with basic auth set
                            if (sAuth.Contains("Basic") && textBoxURL.Text.ToLower().StartsWith("https"))
                            {
                                // Turn on basic auth and try again
                                checkBoxForceBasicAuth.Checked = true;
                                bTriedBasicAuth = false;
                            }
                        }
                    }
                }
                else
                    bTriedBasicAuth = true;
            }

            // Store any cookies we have had returned
            _responseCookies = oSOAP.ResponseCookies;
            if (!checkBoxPersistCookies.Enabled)
            {
                checkBoxPersistCookies.Enabled = true;
                checkBoxPersistCookies.Checked = true;
            }
            buttonSend.Enabled = true;
        }

        private void UpdateTextBoxState()
        {
            this.SuspendLayout();
            textBoxUsername.Enabled = !radioButtonDefaultCredentials.Checked;
            textBoxPassword.Enabled = !radioButtonDefaultCredentials.Checked;
            textBoxDomain.Enabled = !radioButtonDefaultCredentials.Checked && !checkBoxForceBasicAuth.Checked;
            if (!radioButtonDefaultCredentials.Checked)
            {
                groupBoxAuth.Height = 101;
            }
            else
                groupBoxAuth.Height = 42;
            checkBoxForceBasicAuth.Enabled = !radioButtonDefaultCredentials.Checked;
            int i=groupBoxAuth.Location.Y;
            if (groupBoxAuth.Height>groupBoxImp.Height)
            {
                i+=groupBoxAuth.Height;
            }
            else
                i+=groupBoxImp.Height;

            splitContainer1.Top = i + 6;
            splitContainer1.Height = this.Height - splitContainer1.Top - 39;
            this.ResumeLayout(true);
        }

        private void convertIDToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormEWSConvertID oForm = new FormEWSConvertID(textBoxURL.Text, CurrentCredentials, this);
            oForm.Show();
        }

        private string ReadTemplate(string TemplateName)
        {
            string sPath = this.TemplatePath;
            if (String.IsNullOrEmpty(sPath))
                return "";

            string sFile = sPath + "\\" + TemplateName;
            if (!sFile.EndsWith(".xml"))
                sFile += ".xml";

            if (!File.Exists(sFile))
                return "";

            try
            {
                StreamReader oReader = new StreamReader(sFile);
                string sTemplateContent = oReader.ReadToEnd();
                oReader.Close();
                return sTemplateContent;
            }
            catch
            {
                return "";
            }
        }

        private string LoadTemplate(string TemplateName)
        {
            // Reads the XML template
            string sTemplateContent = ReadTemplate(TemplateName);
            if (!String.IsNullOrEmpty(sTemplateContent))
            {
                FormReplaceTemplateFields oForm = new FormReplaceTemplateFields();
                sTemplateContent = oForm.ReplaceTemplateFields(sTemplateContent, this);
                oForm.Dispose();
            }

            return sTemplateContent;
        }

        public bool LoadAndShowTemplate(string TemplateName)
        {
            string sTemplate = LoadTemplate(TemplateName);
            if (String.IsNullOrEmpty(sTemplate))
                return false;
            richTextBoxRequest.Text = sTemplate;
            return true;
        }


        private void buttonSetImpersonation_Click(object sender, EventArgs e)
        {
            SetEWSImpersonation();
        }

        private void SetEWSImpersonation()
        {
            FormEWSSetImpersonation oForm = new FormEWSSetImpersonation(this);
            oForm.GetImpersonationHeader(textBoxImpersonationSID);
            oForm.Dispose();
        }

        private void UpdateSOAPHeader()
        {
            // Add or replace the existing SOAP header with the new one
            string sSOAPRequest = richTextBoxRequest.Text;

            if (sSOAPRequest.ToLower().Contains("<soap:header"))
            {
                // A header already exists, so we need to remove it
                int iHeaderStart = sSOAPRequest.ToLower().IndexOf("<soap:header");
                int iHeaderEnd = sSOAPRequest.ToLower().IndexOf("</soap:header>") + 14;
                while (sSOAPRequest[iHeaderEnd] == '\n' || sSOAPRequest[iHeaderEnd] == '\r')
                    iHeaderEnd++;
                if (iHeaderStart > 0 && iHeaderEnd > 0)
                    sSOAPRequest = sSOAPRequest.Substring(0, iHeaderStart) + sSOAPRequest.Substring(iHeaderEnd);
            }

            string sHeader = EWSHeader();

            if (!String.IsNullOrEmpty(sHeader))
            {
                // Add the SOAP header to this request
                // Need to inject it just before the <soap:Body> tag
                int iBodyTag = sSOAPRequest.ToLower().IndexOf("<soap:body");
                if (iBodyTag > 0)
                {
                    sSOAPRequest = sSOAPRequest.Substring(0, iBodyTag) + sHeader + sSOAPRequest.Substring(iBodyTag);
                    richTextBoxRequest.Text = sSOAPRequest;
                }
                else
                    System.Windows.Forms.MessageBox.Show("Unable to apply impersonation header - please enter valid request", "Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private string EWSHeader()
        {
            // Prepare the EWS header based on version and impersonation settings
            string sHeader = "";

            if (comboBoxRequestServerVersion.Text != "Not set")
            {
                // Set the Exchange version
                sHeader+= "<RequestServerVersion Version=\"" + comboBoxRequestServerVersion.Text + "\" xmlns=\"http://schemas.microsoft.com/exchange/services/2006/types\" />\r\n";
            }

            if (!String.IsNullOrEmpty(textBoxImpersonationSID.Text))
            {
                // Set the impersonation
                string sImpersonation = "<ExchangeImpersonation xmlns=\"http://schemas.microsoft.com/exchange/services/2006/types\">\r\n";
                sImpersonation += "<ConnectingSID>\r\n";

                sImpersonation += "<" + (string)textBoxImpersonationSID.Tag + ">";
                sImpersonation += textBoxImpersonationSID.Text;
                sImpersonation += "</" + (string)textBoxImpersonationSID.Tag + ">";

                sImpersonation += "</ConnectingSID>\r\n";
                sImpersonation += "</ExchangeImpersonation>\r\n";

                sHeader += sImpersonation;
            }

            if (!String.IsNullOrEmpty(sHeader))
                sHeader = "<soap:Header>\r\n" + sHeader + "</soap:Header>\r\n";

            return sHeader;
        }

        private void autodiscoverToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Show warning...
            ClassTemplateReader oReader = new ClassTemplateReader();

            try
            {
                _autodiscoverForm.Credentials = CurrentCredentials;
            }
            catch
            {
                _autodiscoverForm = new FormEWSAutodiscover(CurrentCredentials, textBoxURL, _logger);
            }
            string sSMTPAddress = _userSMTPAddress;
            if (!String.IsNullOrEmpty(textBoxImpersonationSID.Text))
            {
                // If we are using impersonation, we perform autodiscover on the impersonated address
                if ((string)textBoxImpersonationSID.Tag == "PrimarySmtpAddress")
                {
                    sSMTPAddress = textBoxImpersonationSID.Text;
                }
                else
                    sSMTPAddress = "";
            }
            else if (radioButtonSpecificCredentials.Checked)
                if (textBoxUsername.Text.Contains("@"))
                    sSMTPAddress = textBoxUsername.Text;
            _autodiscoverForm.AutodiscoverSMTPAddress = sSMTPAddress;
            _autodiscoverForm.Show(this);
        }

        private void radioButtonDefaultCredentials_CheckedChanged(object sender, EventArgs e)
        {
            UpdateTextBoxState();
        }

        private void radioButtonSpecificCredentials_CheckedChanged(object sender, EventArgs e)
        {
            UpdateTextBoxState();
        }

        private void checkBoxForceBasicAuth_CheckedChanged(object sender, EventArgs e)
        {
            UpdateTextBoxState();
        }

        private void base64ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Encoding.FormBase64 oForm = new Encoding.FormBase64();
            oForm.Show();
        }

        private string TemplatePath
        {
            get
            {
                if (String.IsNullOrEmpty(_templatePath))
                {
                    // Try to set template path
                    string sPath = Path.GetDirectoryName(Application.ExecutablePath) + "\\Templates";
                    if (!Directory.Exists(sPath))
                    {
                        // In case we are running directly from bin folder, we'll try looking for files
                        // where they would be in development environment
                        sPath = Path.GetDirectoryName(Application.ExecutablePath);
                        sPath = Directory.GetParent(sPath).FullName;
                        sPath = Directory.GetParent(sPath).FullName + "\\Templates";
                    }
                    if (Directory.Exists(sPath))
                    {
                        // Check for EWS subfolder.  This is the default, if it exists
                        if (Directory.Exists(sPath + "\\EWS"))
                            sPath += "\\EWS";
                        _templatePath = sPath;
                    }
                }
                return _templatePath;
            }
        }

        private void ReadAvailableTemplates()
        {
            // Read any XML templates available and add to templates combobox
            comboBoxTemplates.Items.Clear();
            buttonLoadTemplate.Enabled = false;
            string[] xmlFiles = null;
            string sPath = TemplatePath;
            if (!Directory.Exists(sPath))
                return;

            try
            {
                xmlFiles = Directory.GetFiles(sPath, "*.xml");
            }
            catch { }

            if (xmlFiles == null) return;

            foreach (string sXMLFile in xmlFiles)
            {
                if (!sXMLFile.ToLower().EndsWith("customfieldtest.xml"))
                {
                    comboBoxTemplates.Items.Add(sXMLFile.Substring(sPath.Length + 1, sXMLFile.Length - 5 - sPath.Length));
                }
                else // We only show CustomFieldTest template when running from IDE
                    if  (System.Diagnostics.Debugger.IsAttached)
                        comboBoxTemplates.Items.Add(sXMLFile.Substring(sPath.Length + 1, sXMLFile.Length - 5 - sPath.Length));
            }
        }

        

        private void buttonLoadTemplate_Click(object sender, EventArgs e)
        {
            richTextBoxRequest.Text = LoadTemplate(comboBoxTemplates.SelectedItem.ToString());
        }

        private void comboBoxTemplates_SelectedIndexChanged(object sender, EventArgs e)
        {
            buttonLoadTemplate.Enabled = !String.IsNullOrEmpty(comboBoxTemplates.SelectedItem.ToString());
        }

        private void hTTPListenerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.HTTPListener.Show();
        }

        private void CopyItemId(RichTextBox SourceTextBox, bool RemoveChangeKey = false, bool IDOnly = false)
        {
            // Read the ItemId at the current cursor position and copy to clipboard
            string sText = SourceTextBox.Text;
            int iCaret = SourceTextBox.SelectionStart;
            int iItemIdStart = sText.LastIndexOf("itemid", iCaret, iCaret,System.StringComparison.CurrentCultureIgnoreCase);
            if (iItemIdStart < 0)
            {
                // No ItemId found, let's look for FolderId
                iItemIdStart = sText.LastIndexOf("folderid", iCaret, iCaret, System.StringComparison.CurrentCultureIgnoreCase);
                if (iItemIdStart < 0) return;
            }
            iItemIdStart = sText.LastIndexOf("<", iItemIdStart, iItemIdStart);
            if (iItemIdStart < 0) return;
            int iItemIdEnd = sText.IndexOf("/>", iItemIdStart)+2;
            if (iItemIdEnd < 0) return;

            string sItemId = sText.Substring(iItemIdStart, iItemIdEnd - iItemIdStart);
            if (!String.IsNullOrEmpty(sItemId))
            {
                SourceTextBox.SelectionStart = iItemIdStart;
                SourceTextBox.SelectionLength = iItemIdEnd - iItemIdStart;
                SourceTextBox.Focus();

                if (IDOnly)
                {
                    // We only want the actual ID (none of the XML)
                    int iIdStart = sItemId.ToLower().IndexOf("id=");
                    if (iIdStart > 0)
                    {
                        iIdStart = sItemId.IndexOf("\"", iIdStart)+1;
                        int iIdEnd = sItemId.IndexOf("\"", iIdStart);
                        if (iIdEnd > iIdStart)
                            sItemId = sItemId.Substring(iIdStart, iIdEnd-iIdStart);
                    }
                }
                else if (RemoveChangeKey)
                {
                    // Remove the ChangeKey from the ItemId
                    int iChangeKeyStart = sItemId.ToLower().IndexOf("changekey");
                    if (iChangeKeyStart > 0)
                    {
                        int iChangeKeyEnd = sItemId.IndexOf("\"", iChangeKeyStart);
                        iChangeKeyEnd = sItemId.IndexOf("\"", iChangeKeyEnd + 1);
                        if (iChangeKeyEnd > iChangeKeyStart)
                            sItemId = sItemId.Substring(0, iChangeKeyStart) + (sItemId.Substring(iChangeKeyEnd + 1));
                    }
                }
            }

            // Now copy to clipboard
            System.Windows.Forms.Clipboard.SetText(sItemId);
        }

        private void MoveTextboxCursor(RichTextBox TextBox)
        {
            try
            {
                int iCharPos = TextBox.GetCharIndexFromPosition(_cursorTracking);
                TextBox.SelectionStart = iCharPos;
                TextBox.SelectionLength = 1;
            }
            catch { }
        }

        private void toolStripResponseCopyItemId_Click(object sender, EventArgs e)
        {
            MoveTextboxCursor(richTextBoxResponse);
            CopyItemId(richTextBoxResponse);
        }

        private void toolStripResponseCopyItemIdNoChangeKey_Click(object sender, EventArgs e)
        {
            MoveTextboxCursor(richTextBoxResponse);
            CopyItemId(richTextBoxResponse, true);
        }

        private void copyItemIdIdOnlyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MoveTextboxCursor(richTextBoxResponse);
            CopyItemId(richTextBoxResponse, false, true);
        }

        private void SelectXMLElementAtCursor(RichTextBox TextBox)
        {
            // Select the XML element at the cursor position
            string sText = TextBox.Text;
            int iStartPos = TextBox.SelectionStart;
            iStartPos = sText.LastIndexOf("<", iStartPos);
            if (sText.Substring(iStartPos + 1, 1) == "/")
            {
                // This is a closing element, so find next...
                iStartPos = sText.LastIndexOf("<", iStartPos-1);
            }
            int iEndPos = sText.IndexOf("/>", iStartPos);
            if (sText.IndexOf(">", iStartPos) < iEndPos)
                iEndPos = -1;
            if (iEndPos < 0)
            {
                // Need to find closing element
                iEndPos = sText.IndexOf(">", iStartPos);
                if (sText.IndexOf(" ", iStartPos) < iEndPos)
                    iEndPos = sText.IndexOf(" ", iStartPos);
                string sTag = sText.Substring(iStartPos + 1, iEndPos - iStartPos - 1);
                string sClosingTag = "</" + sTag;
                iEndPos = sText.IndexOf(sClosingTag, iStartPos) + sClosingTag.Length;
                if (iEndPos > 0)
                    iEndPos = sText.IndexOf(">", iEndPos);
            }
            else
                iEndPos++;
            if (iEndPos > iStartPos)
            {
                TextBox.SelectionStart = iStartPos;
                TextBox.SelectionLength = iEndPos - iStartPos + 1;
                TextBox.Focus();
            }
        }

        private void selectXMLElementToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MoveTextboxCursor(richTextBoxRequest);
            SelectXMLElementAtCursor(richTextBoxRequest);
        }

        private void selectXMLElementToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MoveTextboxCursor(richTextBoxResponse);
            SelectXMLElementAtCursor(richTextBoxResponse);
        }

        private void LogMousePosition(Point CursorPos)
        {
            _cursorTracking = CursorPos;
        }

        private void richTextBoxResponse_MouseUp(object sender, MouseEventArgs e)
        {
            LogMousePosition(new Point(e.X, e.Y));
        }

        private void richTextBoxRequest_MouseUp(object sender, MouseEventArgs e)
        {
            LogMousePosition(new Point(e.X, e.Y));
        }

        private void logViewerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_logViewer == null)
            {
                _logViewer = new FormLogViewer(_logger);
                _logViewer.Show();
                return;
            }
            if (_logViewer.Visible) return;
            try
            {
                _logViewer.Show();
                return;
            }
            catch { }
            _logViewer = new FormLogViewer(_logger);
            _logViewer.Show();
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MoveTextboxCursor(richTextBoxRequest);
            richTextBoxRequest.Paste();
        }

        private void pasteToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MoveTextboxCursor(richTextBoxResponse);
            richTextBoxResponse.Paste();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBoxRequest.Copy();
        }

        private void copyToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            richTextBoxResponse.Copy();
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBoxRequest.Cut();
        }

        private void cutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            richTextBoxResponse.Cut();
        }

        private void richTextBoxRequest_TextChanged(object sender, EventArgs e)
        {
            // Text has changed.  Ensure we don't have leading whitespace

            string sTrimmed = richTextBoxRequest.Text.TrimStart();
            if (sTrimmed == richTextBoxRequest.Text) return;
            richTextBoxRequest.Text = sTrimmed;
        }

        private void contextMenuStripRequest_Opening(object sender, CancelEventArgs e)
        {
            // Enable or disable commands as appropriate
            bool bCutCopyAvailable = (richTextBoxRequest.SelectedText.Length > 0);
            cutToolStripMenuItem.Enabled = bCutCopyAvailable;
            copyToolStripMenuItem.Enabled = bCutCopyAvailable;

            bool bPasteAvailable = System.Windows.Forms.Clipboard.ContainsText();
            pasteToolStripMenuItem.Enabled = bPasteAvailable;
        }

        private void contextMenuStripResponse_Opening(object sender, CancelEventArgs e)
        {
            // Enable or disable commands as appropriate
            bool bCutCopyAvailable = (richTextBoxResponse.SelectedText.Length > 0);
            cutToolStripMenuItem1.Enabled = bCutCopyAvailable;
            copyToolStripMenuItem1.Enabled = bCutCopyAvailable;

            bool bPasteAvailable = System.Windows.Forms.Clipboard.ContainsText();
            pasteToolStripMenuItem1.Enabled = bPasteAvailable;
        }

        private void syntaxHighlightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBoxRequest.Text = richTextBoxRequest.Text; // Clear any existing highlight
            ClassSyntaxHighlighter oHighlighter = new ClassSyntaxHighlighter(richTextBoxRequest);
            oHighlighter.SyntaxHighlight();
            richTextBoxRequest.Update();
        }

        private void syntaxHighlightToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            richTextBoxResponse.Text = richTextBoxResponse.Text; // Clear any existing highlight
            ClassSyntaxHighlighter oHighlighter = new ClassSyntaxHighlighter(richTextBoxResponse);
            oHighlighter.SyntaxHighlight();
            richTextBoxResponse.Update();
        }

        private void textBoxImpersonationSID_TextChanged(object sender, EventArgs e)
        {
            if (textBoxImpersonationSID.Tag == null)
            {
                // We need to specify impersonation type, so we need to open the impersonation window
                SetEWSImpersonation();
            }
        }

        private void testsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }


    }
}
